Popular Searches
Popular Course Categories
Popular Courses

Implementing Login and Logout Using Servlets

Implementing Login and Logout Using Servlets

Web Application Authentication and Security

Implementing Login and Logout Using Servlets

Course: Advanced Java Training

Topic: Implementing Login and Logout Using Servlets

Course Link: Advanced Java Training Course

Demo Link: Register for a Free Course Demo

Official Website: JustAcademy


1. Introduction to Login and Logout Using Servlets

Login and logout functionality is an essential part of most web applications. It allows users to prove their identity before accessing protected resources and provides a controlled way to end their authenticated session. In Java web development, Servlets can process login forms, validate credentials, create sessions, restrict access to private pages, and invalidate sessions during logout.

A typical authentication flow starts when a user enters a username and password. The login Servlet receives the submitted form, validates the credentials against a trusted data source, and creates an HTTP session after successful authentication. The application then uses the session to recognize the authenticated user across multiple HTTP requests. When the user logs out, the application invalidates the session and redirects the user to a public page or login screen.

2. Learning Objectives

  • Understand authentication and session management in Java web applications.
  • Create a login form using HTML.
  • Process login requests using HttpServlet.
  • Validate credentials securely.
  • Create and manage HttpSession objects.
  • Protect pages from unauthenticated access.
  • Implement logout by invalidating the user session.
  • Understand authentication errors, session expiration, and security best practices.

3. Important Concepts

Concept Description
Authentication Verifies the identity of a user using credentials or another authentication method.
Authorization Determines which resources or actions an authenticated user is permitted to access.
Servlet A Java server-side component that handles HTTP requests and generates responses.
HttpSession Stores user-specific state across multiple HTTP requests.
Request Parameter A value submitted through a form, such as a username or password.
Session Invalidation Ends a session and removes its session-scoped data from use.
Redirect Instructs the browser to make a new request to another URL.

4. How Login and Logout Work

4.1 Login Process

  1. The user opens the login page.
  2. The user enters a username and password.
  3. The browser sends an HTTP POST request to the login Servlet.
  4. The Servlet validates the submitted values.
  5. The application checks the credentials against a trusted user repository.
  6. If the credentials are valid, the application creates or establishes an authenticated session.
  7. The user is redirected to a protected page, such as a dashboard.
  8. Subsequent requests are checked to confirm that the session represents an authenticated user.

4.2 Logout Process

  1. The authenticated user selects the logout option.
  2. The browser sends a logout request, preferably using POST.
  3. The logout Servlet invalidates the current session, if one exists.
  4. The application clears authentication-related session state.
  5. The browser is redirected to the login page or another public page.
  6. Any later attempt to open a protected page must be checked again and should require authentication.

5. Project Structure

LoginLogoutApp/
├── src/main/java/
│   └── com/example/auth/
│       ├── LoginServlet.java
│       ├── LogoutServlet.java
│       ├── AuthFilter.java
│       └── UserRepository.java
├── src/main/webapp/
│   ├── login.html
│   ├── dashboard.jsp
│   └── WEB-INF/
│       └── web.xml
└── pom.xml

This is an illustrative Maven web application structure. Servlet API imports and dependency versions should match the application server. Modern Jakarta EE servers use jakarta.servlet, while older Java EE servers use javax.servlet.

6. Creating the Login Form

The login form collects the user's credentials and submits them to the login Servlet. The form uses the POST method so that credentials are not placed directly in the URL query string. HTTPS is still required to protect credentials while they travel over the network.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>User Login</title>
</head>
<body>
    <h1>Login</h1>

    <form action="login" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username"
               autocomplete="username" required>

        <br><br>

        <label for="password">Password:</label>
        <input type="password" id="password" name="password"
               autocomplete="current-password" required>

        <br><br>

        <button type="submit">Login</button>
    </form>
</body>
</html>

Explanation

  • action="login" specifies the URL handled by the login Servlet.
  • method="post" submits the credentials in the request body rather than the URL.
  • name="username" and name="password" define the parameter names read by the Servlet.
  • type="password" masks the characters displayed in the password field but does not encrypt the network request.
  • required provides basic browser-side validation. Server-side validation is still necessary.

7. Implementing LoginServlet

The login Servlet receives the submitted credentials, validates them, and establishes the authenticated session after successful verification. The following example uses a repository interface to keep credential verification separate from HTTP request handling.

package com.example.auth;

import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    private UserRepository userRepository;

    @Override
    public void init() throws ServletException {
        userRepository = new UserRepository();
    }

    @Override
    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response)
            throws ServletException, IOException {

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        if (username == null || password == null
                || username.isBlank() || password.isEmpty()) {
            response.sendError(
                HttpServletResponse.SC_BAD_REQUEST,
                "Username and password are required."
            );
            return;
        }

        boolean validUser =
                userRepository.authenticate(username, password);

        if (validUser) {
            HttpSession oldSession = request.getSession(false);

            if (oldSession != null) {
                oldSession.invalidate();
            }

            HttpSession session = request.getSession(true);
            request.changeSessionId();

            session.setAttribute("authenticatedUser", username);
            session.setMaxInactiveInterval(15 * 60);

            response.sendRedirect(
                request.getContextPath() + "/dashboard.jsp"
            );
        } else {
            response.setStatus(
                HttpServletResponse.SC_UNAUTHORIZED
            );
            request.setAttribute(
                "errorMessage",
                "Invalid username or password."
            );
            request.getRequestDispatcher("/login.jsp")
                   .forward(request, response);
        }
    }
}

Important: This example assumes that UserRepository.authenticate() securely verifies the submitted password. It is not implemented as a plain-text comparison. The referenced login.jsp is an alternative to the static login.html form above; use a JSP login page if you want to display a server-generated error message after forwarding.

Understanding the Code

  • getParameter() reads values submitted by the login form.
  • authenticate() delegates credential verification to the repository layer.
  • getSession(false) checks for an existing session without creating one.
  • invalidate() ends an old session before a new authenticated session is established.
  • getSession(true) creates a session if necessary.
  • changeSessionId() rotates the session ID to help prevent session fixation. It requires a Servlet API version that supports this method.
  • setAttribute() stores the authenticated username in the session.
  • setMaxInactiveInterval() sets the session inactivity timeout in seconds.
  • sendRedirect() redirects the browser to the dashboard after successful login.

8. Implementing a Secure UserRepository

The repository should retrieve the user's stored password hash and verify the submitted password using an established password-hashing library. Passwords should never be stored as plain text or compared against plain-text values stored in the database.

package com.example.auth;

public class UserRepository {

    public boolean authenticate(String username, String password) {
        /*
         * Example implementation outline:
         *
         * 1. Retrieve the account by username using a parameterized query.
         * 2. Read the stored password hash and account status.
         * 3. Verify the submitted password using a suitable password
         *    hashing library, such as Argon2id or bcrypt.
         * 4. Reject disabled, locked, or otherwise ineligible accounts.
         * 5. Return true only if authentication succeeds.
         *
         * Do not implement authentication using a hard-coded password
         * or a plain-text database comparison.
         */

        throw new UnsupportedOperationException(
            "Connect this method to your secure user repository."
        );
    }
}

This is an implementation outline, not a runnable authentication repository. Before deploying the application, replace the placeholder with a real database-backed implementation, secure password-hash verification, account-state checks, and appropriate failure handling.

9. Creating a Dashboard for Authenticated Users

A dashboard can display personalized information for the logged-in user. However, hiding a dashboard link is not sufficient security. The server must verify authentication on every protected request.

<%@ page contentType="text/html; charset=UTF-8" %>
<%
    String username =
        (String) session.getAttribute("authenticatedUser");

    if (username == null) {
        response.sendRedirect(
            request.getContextPath() + "/login.jsp"
        );
        return;
    }
%>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dashboard</title>
</head>
<body>
    <h1>Welcome to the Dashboard</h1>
    <p>You are logged in as
        <%= org.apache.commons.text.StringEscapeUtils.escapeHtml4(username) %>.
    </p>

    <form action="logout" method="post">
        <button type="submit">Logout</button>
    </form>
</body>
</html>

The example uses Apache Commons Text to HTML-escape the username before displaying it. Include the appropriate library dependency if using this approach. An alternative is to use a JSP tag library such as JSTL for output escaping. The logout endpoint must be mapped correctly for the application's context path.

Production recommendation: Prefer a Servlet filter or the application's established security framework to enforce access control centrally rather than repeating authentication checks in individual JSP pages.

10. Implementing LogoutServlet

Logout should terminate the authenticated session on the server. A POST request is preferable to a GET request because logout changes application state and should not be triggered merely by opening a link or by an automated preview.

package com.example.auth;

import java.io.IOException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException {

        HttpSession session = request.getSession(false);

        if (session != null) {
            session.invalidate();
        }

        response.sendRedirect(
            request.getContextPath() + "/login.jsp"
        );
    }
}

Explanation

  • getSession(false) prevents creation of a new session during logout.
  • invalidate() invalidates the existing session and its session-scoped attributes.
  • sendRedirect() sends the browser to the login page.
  • The logout operation is handled through doPost(), not doGet().

Invalidating a session does not necessarily erase every copy of a session identifier from the browser or instantly remove every previously rendered page from the user's screen. Use secure cookie settings, appropriate cache-control headers for private pages, and server-side authentication checks on all protected requests.

11. Configuring Servlet URL Mappings

The examples above use @WebServlet annotations to map Servlet classes to URLs. Alternatively, URL mappings can be configured in WEB-INF/web.xml. Use one consistent configuration approach or ensure that annotation and descriptor mappings do not conflict.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         version="6.0">

    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.example.auth.LoginServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>com.example.auth.LogoutServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/logout</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>15</session-timeout>
        <cookie-config>
            <http-only>true</http-only>
            <secure>true</secure>
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>

</web-app>

This descriptor uses the Jakarta Servlet 6.0 namespace. Use a descriptor version supported by your application server. The secure cookie flag requires HTTPS; configure HTTPS in development and production before enabling it. The inactivity timeout is specified in minutes in web.xml.

12. Protecting Pages with an Authentication Filter

A Servlet filter can intercept requests to protected URLs and check whether an authenticated user is present in the session. This approach centralizes authentication enforcement and reduces the risk of accidentally leaving a page unprotected.

package com.example.auth;

import java.io.IOException;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

@WebFilter(urlPatterns = {"/dashboard.jsp", "/account/*", "/admin/*"})
public class AuthFilter implements Filter {

    @Override
    public void doFilter(
            jakarta.servlet.ServletRequest servletRequest,
            jakarta.servlet.ServletResponse servletResponse,
            FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request =
            (HttpServletRequest) servletRequest;
        HttpServletResponse response =
            (HttpServletResponse) servletResponse;

        HttpSession session = request.getSession(false);

        boolean authenticated =
            session != null
            && session.getAttribute("authenticatedUser") != null;

        if (!authenticated) {
            response.sendRedirect(
                request.getContextPath() + "/login.jsp"
            );
            return;
        }

        chain.doFilter(request, response);
    }
}

Why Use a Filter?

  • Applies authentication checks consistently to mapped protected URLs.
  • Reduces duplicated code across Servlets and JSP pages.
  • Can be extended to enforce roles and permissions.
  • Allows public pages and login endpoints to remain accessible when they are not included in the protected URL patterns.

Review URL mappings carefully. Filters do not protect resources that are outside their configured patterns. For sensitive applications, use a well-maintained security framework and explicit authorization checks for each protected action.

13. Authentication Versus Authorization

Authentication Authorization
Checks who the user is. Checks what the user is allowed to do.
Usually occurs during login or identity verification. Occurs when the user requests a protected resource or action.
May establish an authenticated session. May evaluate roles, permissions, ownership, or other access rules.
Example: verifying a username and password. Example: allowing only an administrator to manage user accounts.

14. Session Management and Security

  • Use HTTPS: Protect credentials and session cookies in transit.
  • Rotate the session ID: Change the session identifier after authentication to reduce session-fixation risk.
  • Use secure cookies: Enable HttpOnly and Secure flags; consider an appropriate SameSite policy.
  • Set an inactivity timeout: Expire inactive sessions after a reasonable period.
  • Invalidate sessions on logout: Remove server-side authenticated session state.
  • Protect against CSRF: Use CSRF tokens or equivalent protections for state-changing requests, including logout where appropriate.
  • Use strong password hashing: Store salted password hashes using a suitable algorithm such as Argon2id or bcrypt, rather than plain-text passwords.
  • Rate-limit login attempts: Apply throttling and monitoring to reduce password-guessing attacks.
  • Use generic login errors: Avoid revealing whether a username exists or whether only the password was incorrect.
  • Do not log passwords: Keep credentials, session IDs, and other secrets out of application logs.

15. Common Errors and Troubleshooting

Problem Possible Cause Solution
Login Servlet is not found Incorrect URL mapping or context path. Verify the Servlet annotation or web.xml mapping and form action.
Username is null The form field name does not match the parameter name. Confirm that the input uses name="username".
Login always fails Repository lookup or password-hash verification is incorrect. Check database connectivity, stored hashes, and verification logic without exposing credentials.
Dashboard redirects to login Session attribute is missing or the filter mapping is incorrect. Check session creation, attribute names, and URL patterns.
Logout does not work Logout request uses the wrong method or endpoint. Submit a POST request to the correct logout mapping.
User appears logged in after logout A stale page is displayed or a protected endpoint is not checking the session. Invalidate the session, enforce server-side checks, and configure private-page cache headers.
Servlet imports fail Code uses a different Servlet namespace than the server. Use jakarta.servlet for modern Jakarta EE servers or javax.servlet for compatible older servers.
Session cookie is not sent Cookie settings, HTTPS configuration, domain, or path are incorrect. Review cookie configuration and verify deployment over the intended protocol.

16. Testing Login and Logout

  1. Open the login page without an existing authenticated session.
  2. Submit empty credentials and verify that server-side validation rejects them.
  3. Submit invalid credentials and verify that authentication fails safely.
  4. Submit valid credentials and confirm that a session is established.
  5. Open the dashboard and verify that the authenticated user can access it.
  6. Open the dashboard directly in a fresh browser session and verify that access is denied or redirected to login.
  7. Log out and verify that the server-side session is invalidated.
  8. Try to access the dashboard again and confirm that authentication is required.
  9. Wait for the session inactivity timeout and verify that protected pages require login again.
  10. Test login throttling, CSRF protections, session-ID rotation, and cookie flags.

17. Mini Project: Login and Logout Application

Project Goal: Build a simple Java web application that authenticates registered users, maintains a session, displays a protected dashboard, and supports secure logout.

Functional Requirements

  • Create a login form with username and password fields.
  • Validate submitted credentials through a repository layer.
  • Store password hashes securely in a database.
  • Create an authenticated session after successful login.
  • Display a personalized dashboard.
  • Protect dashboard and account URLs with an authentication filter.
  • Provide a logout form that invalidates the session.
  • Display safe error messages for failed login attempts.
  • Configure session timeout and secure cookie settings.
  • Test unauthenticated access, invalid credentials, and session expiration.

Expected Result

Users with valid credentials can access the protected dashboard. Users with invalid credentials cannot establish an authenticated session. After logout or session expiration, protected resources require authentication again.

18. Interview Questions and Answers

Q1. What is a login Servlet?

A login Servlet processes submitted login credentials, delegates authentication to a trusted service or repository, and establishes authenticated session state after successful verification.

Q2. Why is HttpSession used in login functionality?

HTTP is stateless. HttpSession helps maintain user-specific state across multiple requests, such as the identity of an authenticated user.

Q3. What is the difference between getSession() and getSession(false)?

getSession() creates a session when one does not exist. getSession(false) returns the existing session or null without creating a new one.

Q4. Why should logout invalidate the session?

Invalidation ends the session and removes its session-scoped data from use, helping ensure that the previous authenticated session is no longer accepted.

Q5. Why should login forms use POST?

POST places submitted credentials in the request body rather than the URL. It does not itself encrypt data, so HTTPS is still essential.

Q6. What is session fixation?

Session fixation is an attack in which an attacker causes a victim to use a session identifier known to the attacker. Rotating the session ID after authentication helps mitigate this risk.

Q7. How can protected pages be secured?

Use server-side authentication checks, typically through a Servlet filter or security framework, and enforce authorization rules on sensitive actions and resources.

Q8. Should passwords be stored in plain text?

No. Passwords should be stored as salted hashes using a suitable password-hashing algorithm, and verified using a trusted library.

Q9. What happens when a session expires?

The session is no longer available for authenticated use. A protected request should therefore redirect the user to login or return an appropriate unauthorized response.

Q10. Why is a GET request not recommended for logout?

GET requests should not perform state-changing operations. A POST request, combined with appropriate CSRF protection, is a better choice for logout.

19. Best Practices Checklist

  • Use HTTPS for all authentication-related traffic.
  • Validate all input on the server.
  • Verify credentials through a secure repository or authentication service.
  • Use a password-hashing algorithm rather than plain-text storage.
  • Rotate session identifiers after successful authentication.
  • Configure session timeout and secure cookie attributes.
  • Protect all sensitive URLs with server-side checks.
  • Use POST for logout and protect state-changing requests against CSRF.
  • Invalidate the session during logout.
  • Keep error messages and logs free of sensitive details.
  • Test login, logout, timeout, and unauthorized-access scenarios.

20. Quick Revision

Method or Feature Purpose
request.getParameter() Reads form parameters.
request.getSession() Returns an existing session or creates one.
request.getSession(false) Checks for an existing session without creating one.
session.setAttribute() Stores authenticated user information in the session.
session.invalidate() Invalidates the current session.
request.changeSessionId() Changes the current session ID when supported by the Servlet API.
response.sendRedirect() Redirects the browser to another URL.
Filter Checks authentication and access rules before a mapped request reaches its target.

21. Conclusion

Implementing login and logout using Servlets introduces important Java web development concepts, including form processing, credential verification, HTTP sessions, protected resources, and access control. A secure implementation must do more than check a username and password: it should use HTTPS, securely hashed passwords, session-ID rotation, appropriate timeouts, protected endpoints, and reliable logout handling. These practices provide a foundation for building safer and more maintainable Java web applications.


Learn More with JustAcademy

Explore the Advanced Java Training Course to learn more about Servlets, JSP, session management, and Java web application development.

Interested in learning more? Register for a Course Demo to explore the training program.

Visit the JustAcademy Homepage to discover additional courses and learning resources.

Previous Next
whatsapp